import {of, from, OperatorFunction, Observable, fromEvent} from "rxjs";
import { map, filter } from 'rxjs/operators'
import { operate } from "rxjs/internal/util/lift";
import {createOperatorSubscriber} from "rxjs/internal/operators/OperatorSubscriber";

import './styles.scss';


function myOperatorPow<T, R>(func: (v: T) => number): OperatorFunction<T, number> {
    return operate((source, subscriber) => {
        source.subscribe(
            createOperatorSubscriber(subscriber, (value: T) => {
                subscriber.next(
                    Math.pow(func(value), 2)
                )
            })
        )
    })
}

class Parent {
    private name: string;
    private age : number;

    static staticValue = 'st'
    constructor(name: string, age: number) {
        this.name = name; this.age = age;
    }
    show() {
        console.log('parent show')
    }
}
class Child extends Parent {
    constructor( name: string,  age: number, private job: string) {
        super(name, age);
    }
    run() {
        console.log('child run')
    }
}

function reT(a: string, b: string) {
    return a + b + (new Date()).toString();
}
// 获取函数返回值类型
type trt = ReturnType<typeof reT>;
let cco: trt = 'abc';

// 获取函数的参数类型
type funcParams = Parameters<typeof reT>
let p: funcParams = ['sss', 'sssf'];

// exclude
type Ex = Exclude<('a' | 'b' | 'c'), 'a'>
type Extr = Extract<('a' | 'b' | 'c'), 'a'>

// pick
type PickType = Pick<{ name: string, age: number }, 'age'>
type OmitType = Omit<{ name: string, age: number }, 'age'>

let aaa: Ex = 'b';
// keyof any = string | number | symbol

// &
type AndType = NonNullable< {name?: string} & { age?: number, address: null }>

let a = {
    name: 'wang', age: 34, address: 'wh'
}

type S = Record<'zorro' | 'wang' | 'david', Partial<typeof a>>

// infer 用法 可以用来推断 参数类型

const reNumberFunc = (param: Parent) => 10;

type GetParamType<T> = T extends (param: infer P) => number ? P : any

type T1 = GetParamType<typeof reNumberFunc>



const personInfo: S = {
    zorro: {name: 'wang'},
    wang: { address: 'wh'},
    david: {age: 30}
}

from([
    { name: 'wang', age: 30 },
    { name: 'ml', age: 12 },
    { name: 'zorro', age: 12 },
    { name: 'lin', age: 12 }
]).pipe(
    map(v => ({...v, id: Math.floor(Math.random() * 1000)})),
    filter(d => d.age < 20),
    myOperatorPow((d) => d.age)
).subscribe(v => {
    console.log(v)
})

const btn = document.querySelector('button')

if (btn) {

    fromEvent(btn, 'click').subscribe((ev) => {
        console.log(ev);
        
    })
}

// type OkCallback = (s: string) => void;

// interface Params {
//     title?: string
// }


// export function confirmDelete(params?: Params): Promise<string> 
// export function confirmDelete(cb: OkCallback, params?: Params): void 
// export function confirmDelete(cb?: OkCallback | Params, params?: Params): Promise<string> | void {
//     let relParams: Params | undefined;
//     if (typeof cb === 'function') {
//         relParams = params;
//         setTimeout(() => {
//             cb(relParams ? relParams.title ?? '' : '');
//         }, 3000);
//     } else {
//         relParams = cb;
//         return new Promise((res, rej) => {
//             setTimeout(() => {
//                 res(relParams ? relParams.title ?? '' : '');
//             }, 3000);
//         }) 
//     }
// }
// confirmDelete().then(res => {
//     console.log(res);
// })

// confirmDelete({title: 'promise'}).then(res => {
//     console.log('promise: ' + res);
// })
// confirmDelete((title: string) => {
//     console.log('funciton: ' + title);
// }, {title: 'title'});

